extends Skill




## 需要移动的回调
## 1. 显示可选范围
## 2. 显示当前选中位置
## 3. 显示当前技能影响的更多范围




@onready var ske = $AS

## 技能范围
var rang: int = 4 # 范围
var igs: Array = [] # 包含自己
var mode := CreateGrid.CREATE_GRID_MODE.TILE_RANGE # 范围模式
## 技能效果
var num: int = 3 # 伤害加成
var direction: Vector2 = Vector2.ZERO # 释放方向
var targets: Array[Unit] = []

## 技能发动代价
var cost_ep: int = 4
var cost_attack_chance: int = 1
var cost_action_chance: int = 2

## 技能[显示图层]与[点击图层]的下标
var area_back: int = -1 # 背景
var area_show: String = "" # 显示

## 技能目标
var cent_pos: Vector2 = Vector2.ZERO
var target_cent: Unit = null
var target_around: Array[Unit] = []




func start(_args: Dictionary = {}) -> void:
	var sce: Scene = get_scene()
	
	var off := sce.map.local_to_map(_args["user"].position)
	var pos := GCreateGrid.create_grid(mode, rang, igs, off)
	var lpos = []
	
	for index in range(0, pos.size()):
		lpos.append(sce.map.map_to_local(pos[index]))
	
	# 生成格子
	# 作为背景
	area_back = sce.select_manage.show_range(
		lpos,
		SceneSelectManage.SelectMangerMode.NONE
	)[0]
	# 更改个颜色
	var layer := sce.select_manage.get_layer_index(area_back)
	for a in layer["areas"]:
		a.modulate = Color8(255, 255, 255, 127)
	
	# 1. 这个技能不能在墙内释放
	# 2、这个技能不能在空白的地方释放
	# 遍历，并删掉多余的区域
	var areas: Array = layer["areas"]
	for i in range(areas.size() - 1, -1, -1): # 从末尾开始遍历
		var a = areas[i]
		# 先判断区域
		var cell: Dictionary = sce.map.get_position_call_top_info(a.position)
		# 如果为空
		if cell.is_empty():
			areas.remove_at(i)
			a.queue_free()
			continue # 进行下一次遍历
		# 如果不可停留
		if not cell["is_stay"]:
			areas.remove_at(i)
			a.queue_free()
			continue # 进行下一次遍历
	# 设置移动的回调
	layer["move_callable"] = call_move
	layer["is_accept_move"] = true
	
	# 生成一个以自己为中心的点（红）
	# 以及衍生的4格范围（淡红）
	# 然后合并两个 layer
	var center = get_master_unit().position
	var size: Vector2 = sce.map.get_tile_size()
	var other = [
		center + Vector2.UP * size,
		center + Vector2.DOWN * size,
		center + Vector2.LEFT * size,
		center + Vector2.RIGHT * size
	]
	var c: String = sce.select_manage.show_range(
		[center],
		SceneSelectManage.SelectMangerMode.SKILL,
		call_check,
		_args
	)[1]
	var cc := sce.select_manage.get_layer_name(c)
	cc["name"] = "黑暗爆破" + c # 给技能层级改名
	area_show = cc["name"]
	for a in cc["areas"]:
		a.modulate = Color8(255, 0, 0, 127)
	var o = sce.select_manage.show_range(
		other,
		SceneSelectManage.SelectMangerMode.NONE
	)[0]
	var oo := sce.select_manage.get_layer_index(o)
	for a in oo["areas"]:
		a.modulate = Color8(255, 127, 0, 127)
	sce.select_manage.merge_layer(oo, cc)
	cc["clear_callable"] = call_clear




func _run() -> void:
	# 支付代价
	var property: UnitProperty = get_master_unit().property
	property.action_chance -= cost_action_chance
	property.attack_chance -= cost_attack_chance
	property.current_ep -= cost_ep
	
	# 播放动画
	ske.position = cent_pos
	ske.show()
	ske.play("default")
	await ske.animation_finished
	ske.hide()
	
	var mu = get_master_unit()
	# 造成伤害
	var harm: int = num + mu.property.ap_special * 0.5
	if is_instance_valid(target_cent):
		target_cent.property.under_attack(mu, {
			"type": "special",
			"harm": harm
		})
	var o: int = harm * 0.5
	for u in target_around:
		u.property.under_attack(u, {
			"type": "special",
			"harm": o
		})
	
	# 重置技能状态
	cent_pos = Vector2.ZERO
	target_cent = null
	target_around.clear()




## 移动回调
func call_move(_args: Dictionary) -> bool:
	# print("call move > ", _args)
	# 获取 show
	var sce: Scene = get_scene()
	var show := sce.select_manage.get_layer_name(area_show)
	# 更改位置
	# 因为合并方法是数组相加，所以第 0 个元素是中心点
	var size: Vector2 = sce.map.get_tile_size()
	var tg: Vector2 = _args["target_position"]
	var other = [
		tg + Vector2.UP * size,
		tg + Vector2.DOWN * size,
		tg + Vector2.LEFT * size,
		tg + Vector2.RIGHT * size
	]
	var areas: Array = show["areas"]
	areas[0].position = tg
	for a in range(1, areas.size()):
		areas[a].position = other[a - 1]
	return true




## 清除回调
func call_clear(_args: Dictionary) -> bool:
	var sce := get_scene()
	sce.select_manage.remove_layer_int(area_back, false)
	sce.select_manage.remove_layer_name(area_show, false)
	return false




## 回调检查
func call_check(_args: Dictionary) -> bool:
	#print("call-check > ", _args)
	var sce: Scene = get_scene()
	# 获取技能图层
	var lay: Dictionary = sce.select_manage.get_layer_name(area_show)
	var ps: PackedVector2Array = []
	for a in lay["areas"]:
		ps.append(a.position)
	# 获取在位置上的所有 unit
	var units := sce.unit_manage.get_position_units(ps)
	# 判断 units 的位置，分成两组
	for u in units:
		if u.position == ps[0]:
			target_cent = u
			units.erase(u)
	target_around = units
	cent_pos = ps[0]
	
	# 不允许空发
	if target_cent != null or not target_around.is_empty():
		_run()
	
	return true




## 需要消耗一个攻击机会
func cost() -> bool:
	if not is_instance_valid(master):
		return false;
	
	# 因为效果的父节点是 UnitSkill
	# 所以访问 Unit 的 master 来获取 unit
	var property: UnitProperty = get_master_unit().property
	if  property.action_chance >= cost_action_chance and \
		property.attack_chance >= cost_attack_chance and \
		property.current_ep >= cost_ep:
		return true
	
	return false
